package com.runa.rccprotocol.analysis;

import com.runa.monitor.comm.dto.newComm.AffiliatePanelVO;
import com.runa.monitor.comm.dto.newComm.PanelVO;
import com.runa.monitor.comm.dto.newComm.ValveVO;
import com.runa.persistence.RepositoryServicePersis;
import com.runa.protocol.analysis.ShellBufferAnalysis;
import com.runa.protocol.dto.DtuReport;
import com.runa.protocol.enums.ByteOrder;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.ConcentratorElectric;
import com.runa.rccprotocol.dto.equdata.ConcenReportData;
import com.runa.rccprotocol.dto.equdata.ElectricityMeterData;
import com.runa.rccprotocol.dto.equdata.ValveData;
import com.runa.rccprotocol.dto.runa.RunaConcenAffirmDeny;
import com.runa.rccprotocol.dto.runa.RunaConcenResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 * @author diandian
 * @Date 2021/10/30 9:25
 */
@Slf4j
public class DaoHengAnalysis extends ShellBufferAnalysis<byte[]> {

    private SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");

    public DaoHengAnalysis() {
        super(null, 0);
    }

    @Override
    public int fill(byte[] data, int size, String n) {
        String prefixStr = new String(data, 0, 2);
        if ("DH".equalsIgnoreCase(prefixStr)) {
            //注册包或者心跳包
            String no = new String(data, 2, 8);
            netEquNo = no;
            interData = new DtuReport(no);
            return size - 10;
        }

        int begin;
        boolean findBegin = false;
        for (begin = 0; begin < size; begin++) {
            int i = data[begin] & 0xff;
            if (i == 0x68) {
                findBegin = true;
                break;
            }
        }
        if (!findBegin) {
            return 0;
        }
        int deviceType = data[begin + 1] & 0xff;
        switch (deviceType) {
            case 0xA3:
                //户阀
                return valveData(data, begin, size);
            default:
                //电表
                return electric(data, begin, size);

        }
//        return 0;
    }

    private int valveData(byte[] data, int start, int size) {
        int index = start;
        index += 2;

        int IDlength = 4;
        String serialNo = ByteUtil.bcd2str(data, index, IDlength, false);
        index += IDlength;

        int factroyLength = 3;
        String factory = ByteUtil.byteToHexString(data, index, factroyLength);
        index += factroyLength;

        int ctr = data[index] & 0xff;

        ++index;
        int len = data[index] & 0xff;
        //数据长度不够，需要返回-1，重新续长度
        if (size < len + start + 13) return -1;

        //cs校验
        boolean csResult = data[start + len + 11] == ByteUtil.sum(data, start, len + 11);
        if (!csResult) {
            return size - start - 2 - index;
        }

        switch (ctr) {
            case 0x81:
                //抄阀
                return data(data, start, size, index, serialNo);
            case 0x84:
                //阀控
                return ctrl(data, start, size, index, serialNo);
        }
        return 0;
    }

    private int ctrl(byte[] data, int start, int size, int index, String serialNo) {
        interData = new RunaConcenAffirmDeny(null, true);
        return size - start - index - 4;
    }

    private int data(byte[] data, int start, int size, int index, String serialNo) {
        ++index;
        //数据标识站两个字节，转成int需要用byteToUShort，如果直接转成short比较会有问题
        Integer flag = ByteUtil.byteToUShort(data, index, ByteOrder.AB);
        boolean flagResult = 0x901D == flag;
        if (!flagResult) {
            return size - index - 4;
        }

        index += 2;
        int ser = data[index] & 0xff;
        if (ser != 0x01) {
            return size - index - 4;
        }

        ++index;
        int frequencyPoint = data[index] & 0xff;

        ++index;
        int signal = ByteUtil.bcdToInt(data[index]);
        int open1 = data[index] & 0xff;

        int inTemLength = 2;
        ++index;
        double inTem = ByteUtil.bcdToInt(data, index, inTemLength, false) * 0.01;

        int outTemLength = 2;
        index += inTemLength;
        double outTem = ByteUtil.bcdToInt(data, index, outTemLength, false) * 0.01;

        int settingTemLength = 2;
        index += outTemLength;
        double settingTem = ByteUtil.bcdToInt(data, index, settingTemLength, false) * 0.01;

        int roomTemLength = 2;
        index += settingTemLength;
        double roomTem = ByteUtil.bcdToInt(data, index, roomTemLength, false) * 0.01;

        int humidityLength = 2;
        index += roomTemLength;
        int humidity = ByteUtil.bcdToInt(data, index, humidityLength, false);

        //最大正温差 1个字节
        index += humidityLength;

        //最大负温差 1个字节
        ++index;

        //设定开度最大值 2个字节
        int settingOpenMaxLength = 2;
        ++index;

        //设定开度最小值 2个字节
        int settingOpenMinLength = 2;
        index += settingOpenMaxLength;

        //当前开度
        int openLength = 2;
        index += settingOpenMinLength;
        int open = ByteUtil.bcdToInt(data, index, openLength, false);

        //道亨需要特殊处理  00 01  表示开度100   50 00 表示开度50  所以降序解数据  50 00 得到 00 50 ，00 01 得到 10 00 ，10 00 则表示为100
        if (open == 1000) {
            open = 100;
        }

        //阀门清洗时间
        index += openLength;

        //累计开阀时间
        int openValveTimeLength = 4;
        ++index;
        int openValveTime = ByteUtil.bcdToInt(data, index, openValveTimeLength, false);

        //设备时间
        int equTimeLength = 6;
        index += openValveTimeLength;
        String equTime = ByteUtil.bcd2str(data, index, equTimeLength, false);


        //状态字1 状态字2 把两个字节合并成一个字符串
        index += equTimeLength;
        String stateCode = ByteUtil.bcd2str(data, index, 2, true);
        int state = ByteUtil.getByBit(data[index], 0);


        ValveVO valveVO = new ValveVO();
        valveVO.setValveSerial(serialNo);
        valveVO.setRemoteSet((float) open1);
        //workTime
        valveVO.setOpenTime((float) openValveTime);
        //settingTemperature
//        valveData.setSetTemperature((float) settingTem);

        valveVO.setSupplyTemp((float) inTem);

        valveVO.setReturnTemp((float) outTem);

        //isLockTemperature 没有
        //settingOpening 没有

        //temperature 室内温度
        short zero = 0;


        //temperatureUp 温度上限
        //temperatureDown 温度下限

        //controlType 控制模式  '非温控','温控'

        valveVO.setActOpen((float) open);

        //switchState 阀门状态
//        valveData.setSwitchState(state == 1);

        valveVO.setStatus(stateCode);

        try {
            valveVO.setValveDate(sdf.parse(equTime));
        } catch (ParseException e) {
            
        }
        valveVO.setReadTime(new Date());

//        valveVO.setFaultCode("");
        RunaConcenResponseData responseData = new RunaConcenResponseData();
        AffiliatePanelVO panel = new AffiliatePanelVO(0, 0, (float) roomTem, zero);
        panel.setSerial(valveVO.getValveSerial());
        panel.setReadTime(valveVO.getReadTime());
        try {
            panel.setId(RepositoryServicePersis.getCommPanelByNetIdAndSerial(
                    RepositoryServicePersis.getCommNetEquipmentByNetSerial(this.netEquNo).getId(),valveVO.getValveSerial()).getId());
            valveVO.getPanelVOList().add(panel);
        }catch (Exception e){
            log.error("户阀挂面板无面板数据---valveData:{}",valveVO,e);
        }
        //温度带面板使用map
//        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
//        stringObjectHashMap.put("valve",valveVO);
//        stringObjectHashMap.put("panel",panel);
        responseData.addRepData(valveVO);
        interData = responseData;
        return size - index - 4;
    }

    private int electric(byte[] data, int start, int size) {
        if (netEquNo == null) {
            return 0;
        }
        if (size - start - 20 < 0) {
            return -1;
        }
        if ((data[start + 19] & 0xff) != 0x16) {
            return 0;
        }
        //        68 95 62 07 16 08 21 68 91 08 33 33 33 33 45 33 33 33 50 16
        int index = start;
        ++index;
        String serial = ByteUtil.byteToHexStringFlip(data, index, 6);
        //cs校验
        boolean csResult = data[start + 18] == ByteUtil.sum(data, start, 18);
        if (!csResult) {
            return 0;
        }

        byte[] el = new byte[4];

        for (int i = 14 + start; i < 18 + start; i++) {
            int datum = (data[i] & 0xff) - 0x33;
            el[i - (14 + start)] = (byte) datum;
        }

        double electricValue = ByteUtil.bcdToInt(el, 0, 4, false) * 0.01;

        RunaConcenResponseData responseData = new RunaConcenResponseData();
        ElectricityMeterData meterData = new ElectricityMeterData();
        meterData.setTotal(electricValue);
        responseData.addRepData(meterData);
        interData = responseData;
        return size - (start + 20);
    }


    public static void main(String[] args) {
        DaoHengAnalysis analysis = new DaoHengAnalysis();
//        String s = "68 95 62 07 16 08 21 68 91 08 33 33 33 33 45 33 33 33 50 16".replace(" ","");
        String s = "FEFE68A3021200115555558124901D010025000081430000000000001010000100000001996489060049331326112131003116".replace(" ", "");
        String s1 = "FEFE " +
                "68 A3 " +
                "23 15 00 11 " +
                "55 55 55 " +
                "81 " +
                "24 " +
                "90 1D " +
                "01 " +
                "00 " +
                "25 " +
                "00 00 " +
                "19 38 " +
                "00 00 00 00 00 00 10 10 00 01 00 00 00 01 99 36 07 05 00 21 21 " +
                "23 12 11 21 31 00 F3 16 ".replace(" ", "");
        System.out.println(s);
        byte[] bytes = ByteUtil.hexStringToByte(s);
        analysis.fill(bytes, bytes.length,"");
        analysis.gain();

        byte[] bytes1 = ByteUtil.hexStringToByte("64");
        int i = bytes1[0] & 0xff;
        System.out.println(i);

        String ss = "FEFEFEFE6840570716082168910833333333586633333616";
        System.out.println(ss.length() / 2);
        byte[] hh = ByteUtil.hexStringToByte(ss);
        analysis.fill(hh, hh.length,"");
        analysis.gain();
    }
}
